package com.ruoyi.netty.handler;

import com.ruoyi.netty.connection.ConnectionManager;
import com.ruoyi.netty.protocol.ModbusMessage;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Modbus服务器处理器
 * 处理Modbus消息和连接状态
 */
@Component
@Slf4j
@ChannelHandler.Sharable
public class ModbusServerHandler extends ChannelInboundHandlerAdapter {

    @Autowired
    private ConnectionManager connectionManager;

    private final AtomicInteger requestCounter = new AtomicInteger(0);

    /**
     * 新连接建立
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.info("New connection established: {}", ctx.channel().remoteAddress());
        connectionManager.addConnection(ctx.channel());
    }

    /**
     * 连接断开
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.info("Connection closed: {}", ctx.channel().remoteAddress());
        connectionManager.removeConnection(ctx.channel());
    }

    /**
     * 处理Modbus消息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        // 使用Java 8兼容的instanceof检查
        if (msg instanceof ModbusMessage) {
            handleModbusMessage(ctx, (ModbusMessage) msg);
        }
    }

    /**
     * 处理异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("Channel exception: {}", cause.getMessage());
        ctx.close();
    }

    /**
     * 处理空闲状态事件
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        // 使用Java 8兼容的instanceof检查
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                log.warn("Channel idle timeout: {}", ctx.channel().remoteAddress());
                ctx.close();
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    /**
     * 处理Modbus消息的具体逻辑
     */
    private void handleModbusMessage(ChannelHandlerContext ctx, ModbusMessage message) {
        try {
            log.debug("Received {} request from unit {}", 
                    message.getFunctionName(), message.getUnitId());

            // 根据功能码处理不同类型的请求
            switch (message.getFunctionCode()) {
                case 1: // 读线圈
                case 2: // 读离散输入
                    handleReadDigitalInputs(ctx, message);
                    break;
                    
                case 3: // 读保持寄存器
                case 4: // 读输入寄存器
                    handleReadRegisters(ctx, message);
                    break;
                    
                case 5: // 写单个线圈
                case 6: // 写单个寄存器
                    handleWriteSingle(ctx, message);
                    break;
                    
                case 15: // 写多个线圈
                case 16: // 写多个寄存器
                    handleWriteMultiple(ctx, message);
                    break;
                    
                default:
                    sendExceptionResponse(ctx, message, 1); // 非法功能
                    break;
            }
            
        } catch (Exception e) {
            log.error("Error processing Modbus message: {}", e.getMessage());
            sendExceptionResponse(ctx, message, 4); // 服务器故障
        }
    }

    /**
     * 处理读取数字输入的请求
     */
    private void handleReadDigitalInputs(ChannelHandlerContext ctx, ModbusMessage request) {
        // TODO: 实现读取数字输入的逻辑
    }

    /**
     * 处理读取寄存器的请求
     */
    private void handleReadRegisters(ChannelHandlerContext ctx, ModbusMessage request) {
        // TODO: 实现读取寄存器的逻辑
    }

    /**
     * 处理单个写入的请求
     */
    private void handleWriteSingle(ChannelHandlerContext ctx, ModbusMessage request) {
        // TODO: 实现单个写入的逻辑
    }

    /**
     * 处理多个写入的请求
     */
    private void handleWriteMultiple(ChannelHandlerContext ctx, ModbusMessage request) {
        // TODO: 实现多个写入的逻辑
    }

    /**
     * 发送异常响应
     */
    private void sendExceptionResponse(ChannelHandlerContext ctx, ModbusMessage request, int exceptionCode) {
        ModbusMessage response = new ModbusMessage();
        response.setTransactionId(request.getTransactionId());
        response.setProtocolId(request.getProtocolId());
        response.setUnitId(request.getUnitId());
        response.setFunctionCode((byte) (request.getFunctionCode() | 0x80)); // 设置异常功能码
        
        // 发送响应
        ctx.writeAndFlush(response);
    }
} 